import Club from '../../database/models/club'
import ClubMember from '../../database/models/clubMember'
import Lobby from '../../match/doudizhu/centerlobby'
import {AsyncRedisClient} from "../../utils/redis"
import {ISocketPlayer} from "../ISocketPlayer"

export function lobbyQueueNameFrom(gameType: string) {
  return `${gameType}Lobby`
}

async function playerCanInClubRoom(player, clubId, gameType) {

  if (!clubId) {
    return false;
  }
  const ownerClub = await Club.findOne({_id: clubId})
  if (ownerClub && ownerClub.owner === player.model._id) {
    return true;
  }

  const clubMemberInfo = await ClubMember.findOne({
    member: player.model._id,
    club: clubId,
    gameType: gameType
  })

  if (clubMemberInfo) {
    return true
  }
  return false;
}

export function createHandler(redisClient: AsyncRedisClient) {

  async function isInTournaQueue(playerId: string, gameType: string): Promise<boolean> {
    const tId = await redisClient.hgetAsync(`u:${playerId}`, `'t:${gameType}`)
    return !!tId
  }


  const handlers = {
    'room/reconnect': async (player, message) => {
      const room = await Lobby.getInstance().getDisconnectedRoom(player._id)
      if (room) {
        player.currentRoom = room
        player.setGameName(message.gameType)
        player.requestToCurrentRoom('room/reconnect')
      }
    },

    'room/join-friend': async (player, message) => {

      if (await isInTournaQueue(player._id, message.gameType)) {
        return player.sendMessage('room/join-fail', {reason: '在比赛场排队中'})
      }

      const lobby = Lobby.getInstance();

      const roomInfo = await lobby.getRoomInfo(message._id);

      if (roomInfo.clubMode && !await playerCanInClubRoom(player, roomInfo.clubId, message.gameType)) {
        player.sendMessage('room/join-fail', {reason: '该房间为亲友圈房间, 非该亲友圈成员无法加入'});
        return
      }

      const roomExists = await lobby.isRoomExists(message._id)
      if (roomExists) {
        player.setGameName(message.gameType)
        player.requestToRoom(message._id, 'joinRoom', message)
      } else {
        player.sendMessage('room/join-fail', {reason: '房间不存在'})
      }
    },

    'room/create': async (player, message) => {

      if (await isInTournaQueue(player._id, message.gameType)) {
        return player.sendMessage('room/join-fail', {reason: '在比赛场排队中'})
      }


      let rule = message.rule
      const gameType = rule.type || 'paodekuai'
      player.setGameName(message.gameType)
      player.requestTo(lobbyQueueNameFrom(gameType), 'createRoom', {rule, gameType})
      return
    },

    'room/createForClub': async (player, message) => {

      if (await isInTournaQueue(player._id, message.gameType)) {
        return player.sendMessage('room/join-fail', {reason: '在比赛场排队中'})
      }
      let rule = message.rule

      if (rule.share) {
        if (player.model.gem < 1) {
          player.sendMessage('room/join-fail', {reason: '房卡不足 无法创建房间。'})
          return
        }
      } else {
        if (player.model.gem < 4) {
          player.sendMessage('room/join-fail', {reason: '房卡不足 无法创建房间。'})
          return
        }
      }
      const gameType = rule.type || 'paodekuai'
      player.requestTo(lobbyQueueNameFrom(gameType), 'createClubRoom', {rule, gameType})
      return
    },

    'room/next-game': (player) => {
      player.requestToCurrentRoom('room/next-game')
    },
    'room/leave': (player) => {
      player.requestToCurrentRoom('room/leave')
    },

    'room/ready': (player) => {
      player.requestToCurrentRoom('room/ready', {})
    },
    'room/creatorStartGame': (player) => {
      player.requestToCurrentRoom('room/creatorStartGame', {})
    },
    'room/sound-chat': (player, message) => {
      player.requestToCurrentRoom('room/sound-chat', message)
    },

    'room/buildInChat': (player, message) => {
      player.requestToCurrentRoom('room/buildInChat', message)
    },

    'room/addShuffle': (player) => {
      player.requestToCurrentRoom('room/addShuffle');
    },

    'room/dissolve': (player: ISocketPlayer) => {
      player.requestToCurrentRoom('room/dissolve')
    },

    'room/dissolveReq': (player: ISocketPlayer) => {
      player.requestToCurrentRoom('room/dissolveReq')
    },
    'room/AgreeDissolveReq': (player: ISocketPlayer) => {
      player.requestToCurrentRoom('room/AgreeDissolveReq')
    },
    'room/DisagreeDissolveReq': (player) => {
      player.requestToCurrentRoom('room/DisagreeDissolveReq')
    },
    'room/forceDissolve': (player, message) => {
      player.forceCloseRoom(message.gameType, message.roomNum)
    },
  }

  return handlers
}

